from django.conf import settings
from django.shortcuts import render

# Create your views here.
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework_jwt.views import ObtainJSONWebToken

from collect.merge_cart_cookie_to_redis import merge_collect_cookie_to_redis
from users.models import User
from users import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from rest_framework.generics import CreateAPIView, RetrieveAPIView, UpdateAPIView


class UsernameCountView(APIView):
    """
    用户名数量
    """
    def get(self, request, username):
        """
        获取指定用户名数量
        """
        count = User.objects.filter(username=username).count()

        data = {
            'username': username,
            'count': count
        }

        return Response(data)


class MobileCountView(APIView):
    """
    手机号数量
    """
    def get(self, request, mobile):
        """
        获取指定手机号数量
        """
        count = User.objects.filter(mobile=mobile).count()

        data = {
            'mobile': mobile,
            'count': count
        }

        return Response(data)

class UserView(CreateAPIView):
    """
    用户注册
    """
    serializer_class = serializers.CreateUserSerializer


class UserDetailView(RetrieveAPIView):
    """
    用户详情
    """
    serializer_class = serializers.UserDetailSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        return self.request.user


class EmailView(UpdateAPIView):
    """
    保存用户邮箱
    """
    permission_classes = [IsAuthenticated]
    serializer_class = serializers.EmailSerializer

    def get_object(self, *args, **kwargs):
        return self.request.user


class VerifyEmailView(APIView):
    """验证邮箱"""
    def get(self, request):
        """
        验证邮箱,将用户数据中的邮箱状态置为真
        :param request:
        :return:
        """
        # 获取token
        token = request.query_params.get('token')
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(token)
        except:
            return Response({"errors":"token无效"}, status=status.HTTP_400_BAD_REQUEST)

        # 查找用户
        username = data.get("username")
        print("username:{}".format(username))
        try:
            user = User.objects.get(username=username)
        except:
            return Response({"errors":"用户不存在"},status=status.HTTP_400_BAD_REQUEST)

        # 更改用户邮箱验证状态
        user.email_active = True
        user.save()
        return Response({"message":True})


class UserAuthorizeView(ObtainJSONWebToken):
    """
    用户认证
    """
    def post(self, request, *args, **kwargs):
        # 调用父类的方法，获取drf jwt扩展默认的认证用户处理结果
        response = super().post(request, *args, **kwargs)

        # 仿照drf jwt扩展对于用户登录的认证方式，判断用户是否认证登录成功
        # 如果用户登录认证成功，则合并收藏图书
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data.get('user')
            response = merge_collect_cookie_to_redis(request, user, response)

        return response


class UpdatePasswdView(APIView):
    """
        修改密码
    """
    def put(self, request, pk):
        data = request.data
        user = User.objects.get(id=pk)
        if not user.check_password(data['old_password']):
            return Response({'message': '原密码输入有误!'}, status=status.HTTP_412_PRECONDITION_FAILED)
        if data['password'] != data['password2']:
            return Response({'message': '两次密码不一致，请重新输入'}, status=status.HTTP_412_PRECONDITION_FAILED)
        if user.check_password(data['password']):
            return Response({'message': '与原密码相同!'}, status=status.HTTP_412_PRECONDITION_FAILED)

        user.set_password(data['password'])
        user.save()
        return Response({'message':'ok'})

    def post(self, request, pk):
        """
        忘记密码第三部:更新密码
        :param request:
        :param pk:
        :return:
        """
        data = request.data
        user = User.objects.get(id=pk)
        # 修改病并保存
        if data['password'] != data['password2']:
            raise Exception('两次密码不一致，请重新输入')
        user.set_password(data['password'])
        user.save()
        return Response({'message': 'ok'})


class VerificationAccountView(APIView):
    """忘记密码:1.验证用户"""
    def get(self,request, name):
        """
        实现忘记密码,验证用户
        /accounts/python/sms/token/
        ?text=urvb&
        image_code_id=05b22d3a-a034-42a8-8135-bb77bb98eb72
        :param request:
        :param name:
        :return:
        """
        # print(name)
        imgcode = request.query_params["text"].lower()
        image_code_id = request.query_params["image_code_id"]
        # 1.查询用户
        try:
            user = User.objects.filter(username=name)[0]
        except:
            return Response({"errors":"找不到用户"}, status=400)
        # 2.教研图片验证码
        # 建立链接
        conn = get_redis_connection("verify_codes")
        # 获取img_code
        try:
            real_imgcode = conn.get("img_%s" % image_code_id).decode().lower()
        except:
            return Response({"errors":"图片验证码获取失败"},status=405)
        if not real_imgcode:
            return Response({"errors": "图片验证码失效"}, status=406)
        if real_imgcode != imgcode:
            return Response({"errors": "图片验证码错误"}, status=407)
        # 生成token
        mobile = user.mobile
        tjs = TJS(settings.SECRET_KEY, 300)
        token = tjs.dumps({"mobile": mobile}).decode()
        return Response({"mobile": user.mobile, "access_token":token})


class SendSMSView(APIView):
    """忘记密码第二部:发送短信验证码"""
    # SMS_CODEView
    pass


class VerificationSMSView(APIView):
    """忘记密码第二部:验证短信验证码"""
    def get(self,request, name):
        """
        验证短信密码
        /accounts/python/password/token/
        ?sms_code=576061
        :param request:
        :param name:
        :return:
        """
        # 1.获取用户名
        print(name)
        # 2.获取短信验证码
        smscode = request.query_params["sms_code"]

        # 验证短信验证码
        # 获取redis中的真实验证码
        conn = get_redis_connection("verify_codes")
        # 获取手机号
        user = User.objects.filter(username=name)[0]
        mobile = user.mobile
        try:
            real_sms = conn.get("sms_%s" % mobile).decode()
        except:
            return Response({"errors":"短信验证么获取失败"},status=400)
        if not real_sms:
            return Response({"errors":"短信验证码过期"}, status=405)
        if real_sms != smscode:
            return Response({"errors": "短信验证码错误"}, status=406)
        # 获取user_id和access_token
        user_id = user.id
        mobile = user.mobile
        tjs = TJS(settings.SECRET_KEY, 300)
        token = tjs.dumps({"mobile": mobile}).decode()

        return Response({"user_id":user_id,
                         "access_token":token
                         }, status=200)

